package com.hzncc.scaffold.controller.Front.User;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzncc.scaffold.core.ResultT;
import com.hzncc.scaffold.entity.Other.Tag;
import com.hzncc.scaffold.entity.Other.User;
import com.hzncc.scaffold.entity.Other.Usertag;
import com.hzncc.scaffold.entity.Vo.LoginSuccessVo;
import com.hzncc.scaffold.entity.Vo.LoginVo;
import com.hzncc.scaffold.entity.Vo.RegistVo;
import com.hzncc.scaffold.entity.Vo.ResetPwdVo;
import com.hzncc.scaffold.service.TagService;
import com.hzncc.scaffold.service.UserService;
import com.hzncc.scaffold.service.UsertagService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: DrunkBear
 * @Date: 2022-06-01 16:03
 * @Description: null
 */

@RestController
@RequestMapping("/user")
@Api(tags = "前台接口-前台用户管理")
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    UsertagService usertagService;

    @Autowired
    TagService tagService;

    @PostMapping("/login")
    @ApiOperation("用户登录")
    public ResultT login(@RequestBody LoginVo loginVo) {

        String account = loginVo.getAccount();
        String password = loginVo.getPassword();

        if (StrUtil.isEmpty(account) || StrUtil.isEmpty(password)) {
            return ResultT.fail("数据错误");
        }
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.ne(User::getRole, "超级管理员");
        lqw.ne(User::getRole, "子管理员");
        lqw.eq(StrUtil.isNotEmpty(account), User::getAccount, account).or().eq(StrUtil.isNotEmpty(account), User::getIdCardNum, account).or().eq(StrUtil.isNotEmpty(account), User::getTelephone, account);
        lqw.eq(User::getIsDelete, 0);

        if (userService.getOne(lqw) == null) {
            return ResultT.fail("账号密码错误");
        }

        User user = userService.getOne(lqw);
        String userPassword = user.getPassword();
        if (user.getRole().equals("超级管理员") && !user.getRole().equals("子管理员")) {
            return ResultT.fail();
        }
        if (user.getStatus() == 1) {
            return ResultT.fail("账户已冻结,无法继续使用");
        }
        if (BCrypt.checkpw(password, userPassword)) {
            StpUtil.login(user.getId());

            LoginSuccessVo loginSuccessVo = BeanUtil.copyProperties(user, LoginSuccessVo.class, "routeAuth");

            ArrayList<String> routeAuth = new ArrayList<>();
            if (StrUtil.isNotEmpty(user.getRouteAuth())) {
                routeAuth = (ArrayList<String>) StrUtil.split(user.getRouteAuth(), ",");
            }
            loginSuccessVo.setUserId(user.getId());
            loginSuccessVo.setRouteAuth(routeAuth);
            loginSuccessVo.setToken(StpUtil.getTokenValue());

            int loginIdAsInt = StpUtil.getLoginIdAsInt();
            System.out.println("登录信息："+loginIdAsInt);
            return ResultT.success(loginSuccessVo);
        } else {
            return ResultT.fail("账号密码错误");
        }
    }

    @PostMapping("/logout")
    @ApiOperation("注销")
    public ResultT logout() {
        StpUtil.logout();
//        StpUtil.kickout(StpUtil.getLoginIdAsInt());
        return ResultT.success("注销成功");
    }

    @GetMapping("/checkPhone")
    @ApiOperation("检查电话号码是否已注册")
    public Map<String,Object> checkPhone(String telephone) {
        Boolean isExist = userService.checkPhone(telephone);
        Map<String,Object> map = new HashMap<>();
        map.put("code",200);
        map.put("isExist",isExist);
        map.put("message","操作成功");
        return map;
    }

    @PostMapping("/regist")
    @ApiOperation("注册")
    public ResultT regist(@RequestBody RegistVo registVo) {
        Boolean aBoolean = userService.checkPhone(registVo.getTelephone());
        if (redisTemplate.opsForValue().get(registVo.getTelephone()) == null) {
            return ResultT.fail("验证码错误或失效");
        }

        String realCaptcha = (String) redisTemplate.opsForValue().get(registVo.getTelephone());

        if (aBoolean) {
            return ResultT.fail("该手机号码已被注册");
        }

        if (!realCaptcha.equals(registVo.getCaptcha())) {
            return ResultT.fail("验证码错误或失效");
        }

        if (registVo.getPassword().length() < 6) {
            return ResultT.fail("密码格式错误");
        }

        if (registVo.getPassword().length() > 16) {
            return ResultT.fail("密码格式错误");
        }

        User user = new User();
        user.setName(registVo.getUsername());
        user.setTelephone(registVo.getTelephone());

        String gensalt = BCrypt.gensalt();
        String password = BCrypt.hashpw(registVo.getPassword(), gensalt);

        user.setPassword(password);
        user.setRole(registVo.getRole());
        user.setAccount(StrUtil.toString(System.currentTimeMillis()));
        user.setInfo("");
        if ("学校".equals(registVo.getRole()) || "企业".equals(registVo.getRole())) {
            user.setInstituteName(registVo.getUsername());
        }

        boolean save = userService.save(user);

        if (save) {

            Integer userId = user.getId();

            LambdaQueryWrapper<Tag> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Tag::getName, registVo.getRole());
            Tag tag = tagService.getOne(lqw);

            Usertag usertag = new Usertag();
            usertag.setTagId(tag.getId());
            usertag.setUserId(userId);
            usertagService.save(usertag);

            //移除验证码
            redisTemplate.delete(registVo.getTelephone());

            return ResultT.success(userId);
        } else {
            return ResultT.fail("操作失败");
        }
    }

    @PostMapping("/resetPwd")
    @ApiOperation("重设密码")
    public ResultT resetPwd(@RequestBody ResetPwdVo resetPwdVo) {

        if (!userService.checkPhone(resetPwdVo.getTelephone())) {
            return ResultT.fail("该用户未注册");
        }

        if (redisTemplate.opsForValue().get(resetPwdVo.getTelephone()) == null) {
            return ResultT.fail("验证码错误或失效");
        }

        if (resetPwdVo.getNewPwd().length() < 6) {
            return ResultT.fail("密码格式错误");
        }

        if (resetPwdVo.getNewPwd().length() > 16) {
            return ResultT.fail("密码格式错误");
        }

        String realCaptcha = (String) redisTemplate.opsForValue().get(resetPwdVo.getTelephone());

        if (!StrUtil.equals(resetPwdVo.getCaptcha(), realCaptcha)) {
            return ResultT.fail("验证码错误或失效");
        }

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getTelephone, resetPwdVo.getTelephone());
        User user = userService.getOne(lqw);

        String gensalt = BCrypt.gensalt();
        String newPassword = BCrypt.hashpw(resetPwdVo.getNewPwd(), gensalt);

        user.setPassword(newPassword);
        boolean update = userService.updateById(user);
        if (update) {
            return ResultT.success("操作成功");
        } else {
            return ResultT.fail("操作失败");
        }
    }
}
